package com.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.demo.core.constants.HttpStatus;
import com.demo.core.domain.Result;
import com.demo.core.exception.ParameterException;
import com.demo.domain.User;
import com.demo.domain.UserDTO;
import com.demo.domain.UserRequest;
import com.demo.domain.ro.CancelUserRequest;
import com.demo.domain.ro.ModifyPwdByOldPwdRequest;
import com.demo.domain.ro.ModifyPwdRequest;
import com.demo.domain.ro.ModifyUserInfoRequest;
import com.demo.service.MailService;
import com.demo.service.UserService;
import com.demo.utils.Token;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
@CrossOrigin("")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private MailService mailService;

    // 发送验证码到邮箱中
    @PostMapping("/sendEmail")
    @ResponseBody
    public String sendEmail(String email, HttpServletRequest request) throws ParameterException {
        if (email == null || email.equals("")) {
            throw new ParameterException("email为空");
        }
        if (!email.contains("@")) {
            throw new ParameterException("email值非法");
        }
        // 获取当前会话
        HttpSession httpSession = request.getSession();
        String id = httpSession.getId();
        Object[] obj = mailService.sendMail(email, httpSession);
        if (obj == null) {
            return "false";
        }
        httpSession.setAttribute("email:", obj[0]);
        httpSession.setAttribute("code" + id, obj[1]);
        System.out.println(obj[0]);
        System.out.println(obj[1]);
        return "succeed";
    }

    // 假设这是处理修改密码请求的接口
//    验证用户输入的验证码和实际的验证码是否匹配
    @PostMapping("/mateCode")
    public ResponseEntity<String> mateCode(String code, String email, HttpServletRequest request) throws ParameterException {
        if (code.length() != 6) {
            throw new ParameterException("code值非法");
        }
        if (email == null || email.equals("")) {
            throw new ParameterException("email为空");
        }
        if (!email.contains("@")) {
            throw new ParameterException("email值非法");
        }
        if (request == null) {
            throw new ParameterException("request为null");
        }
        HttpSession session = request.getSession();
        UserDTO userDTO = new UserDTO();
        userDTO.setCode(code);
        userDTO.setEmail(email);
        // 验证验证码是否一致
        boolean isCodeValid = mailService.validateCode(userDTO, session);
        if (!isCodeValid) {
            return ResponseEntity.status(org.springframework.http.HttpStatus.BAD_REQUEST).body("验证码不正确或已失效");
        } else {
            return ResponseEntity.ok("验证码正确");
        }
    }

    /**
     * 作用同上方sendEmail方法，改名改返回格式
     *
     * @param email
     * @param request
     * @return
     */
    @Operation(summary = "发送验证码")
    @PostMapping("getCode")
    public Result getCode(String email, HttpServletRequest request) throws ParameterException {
        if (email == null || email.equals("")) {
            throw new ParameterException("email为空");
        }
        if (!email.contains("@") || !email.contains(".")) {
            throw new ParameterException("email值非法");
        }
        if (request == null) {
            throw new ParameterException("request为null");
        }
        // 获取当前会话
        HttpSession httpSession = request.getSession();
        String id = httpSession.getId();
        Object[] obj = mailService.sendMail(email, httpSession);
        httpSession.setAttribute("email:", obj[0]);
        httpSession.setAttribute("code" + id, obj[1]);
        return obj[1] != null || obj[1].equals("") == false ?
                Result.success(HttpStatus.SUCCESS, "验证码发送成功", null) :
                Result.error("验证码发送失败，请重新尝试");
    }

    /**
     * 根据学号找到邮箱，发送验证码到所绑定的邮箱中
     *
     * @param uid
     * @param request
     * @return
     */
    @Operation(summary = "得到发送给某个uid的验证码")
    @PostMapping("/getCodeByID")
    public Result getCodeByID(Long uid, HttpServletRequest request) throws ParameterException {
        if (uid == null || uid <= 0l) {
            throw new ParameterException("uid为null或数值非法");
        }
        if (request == null) {
            throw new ParameterException("request为null");
        }
        List<String> list = userService.getCodeByID(uid, request);
        return list != null ? Result.success(HttpStatus.SUCCESS, "操作成功", list)
                : Result.error("获取验证码失败");
    }

    /**
     * 修改密码
     *
     * @param modifyPwdRequest
     * @param request
     * @return
     */
    @Operation(summary = "修改密码", description = "根据邮箱、验证码、新密码")
    @PostMapping("/modifyPassword")
    public Result modifyPassword(@RequestBody ModifyPwdRequest modifyPwdRequest, HttpServletRequest request) throws Exception {
        if (modifyPwdRequest == null) {
            throw new ParameterException("userRequest为空");
        }
        String code = modifyPwdRequest.code;
        String email = modifyPwdRequest.email;
        String newPwd = modifyPwdRequest.newPwd;
        if (code.length() != 6) {
            throw new ParameterException("code值非法");
        }
        if (email == null || email.equals("") || !email.contains("@") || !email.contains(".")) {
            throw new ParameterException("email为空或值非法");
        }
        if (newPwd == null || newPwd.length() > 15 || newPwd.length() < 6 || newPwd.length() < 0) {
            throw new ParameterException("newpw为null或长度非法");
        }
        if (request == null) {
            throw new ParameterException("request为null");
        }
        String msg = userService.modifyPwBeforeLogin(code, email, newPwd, request);
        return Result.success(HttpStatus.SUCCESS, msg, null);
    }

    /**
     * 在个人信息界面修改密码
     * 形参：学号，原密码，新密码，验证码
     *
     * @param modifyByOldPwdRequest
     * @param request
     * @return
     */
    @Operation(summary = "修改密码", description = "根据uid、新密码、旧密码、验证码")
    @PostMapping("/modifyPwByOriginalPw")
    public Result modifyPwByOriginalPw(@RequestBody ModifyPwdByOldPwdRequest modifyByOldPwdRequest, HttpServletRequest request) throws Exception {
        if (modifyByOldPwdRequest == null) {
            throw new ParameterException("userRequest为空");
        }
        Long uid = modifyByOldPwdRequest.uid;
        String newPwd = modifyByOldPwdRequest.newPwd;
        String originalPwd = modifyByOldPwdRequest.originalPwd;
        String code = modifyByOldPwdRequest.code;
        if (code.length() != 6) {
            throw new ParameterException("code值非法");
        }
        if (uid == null) {
            throw new ParameterException("uid为空或者值非法");
        }
        if (newPwd == null || newPwd.length() == 0 ||
                originalPwd == null || originalPwd.length() == 0) {
            throw new ParameterException("newPw或originalPw为null");
        }
        if (newPwd.length() > 15 || newPwd.length() < 6 || newPwd.length() < 0 ||
                originalPwd.length() > 15 || originalPwd.length() < 6 || originalPwd.length() < 0) {
            throw new ParameterException("newPw或originalPw值非法");
        }
        if (request == null) {
            throw new ParameterException("Uequest为null");
        }
        List<Boolean> list = userService.modifyPwByOriginalPw(uid, originalPwd, newPwd, code, request);
//        根据service层返回的列表来返回提示信息
        if (list == null) {
            return Result.error("账号不存在或已注销");
        }
//        list(0)得到传来的原密码与数据库密码的匹配结果
        if (!list.get(0)) {
            return Result.error("原密码输入错误");
        }
//        list(1)得到验证码输入是否正确
        if (!list.get(1)) {
            return Result.error("验证码输入错误");
        }
//        list(2)得到对数据库进行操作的成功与否
        if (!list.get(2)) {
            return Result.error("修改密码失败，请联系管理员进行修改");
        }
        return Result.success(HttpStatus.SUCCESS, "修改密码成功", null);
    }

    /**
     * 注销账号
     *
     * @param cancelUserRequest
     * @param request
     * @return
     */
    @Operation(summary = "注销账号", description = "根据验证码、邮箱、密码")
    @PostMapping("/cancelAccount")
    public Result cancelAccount(@RequestBody CancelUserRequest cancelUserRequest, HttpServletRequest request) throws Exception {
        if (cancelUserRequest == null) {
            throw new ParameterException("userRequest为空");
        }
        String code = cancelUserRequest.code;
        String email = cancelUserRequest.email;
        String pwd = cancelUserRequest.pwd;
        if (code.length() != 6) {
            throw new ParameterException("code值非法");
        }
        if (email == null || email.equals("") || !email.contains("@") || !email.contains(".")) {
            throw new ParameterException("email为空/值非法");
        }
        if (pwd == null || pwd.length() > 15 || pwd.length() < 6 || pwd.length() < 0) {
            throw new ParameterException("pwd为null或长度非法");
        }
        if (request == null) {
            throw new ParameterException("request为null");
        }
        String msg = userService.cancelAccount(code, email, pwd, request);
        return Result.success(HttpStatus.SUCCESS, msg, null);
    }

    /**
     * 获取session对象的uid
     * HttpSession是接口，session是该接口实现类的实例对象
     * return 当前登录用户的uid值
     */
    protected final Long getUidFromSession(HttpSession session) throws ParameterException {
        if (session == null) {
            throw new ParameterException("session为null");
        }
        return Long.valueOf(session.getAttribute("uid").toString());
    }

    //获取当前登录用户的真实姓名
    protected final String getURealNameFromSession(HttpSession session) throws ParameterException {
        if (session == null) {
            throw new ParameterException("session为null");
        }
        return session.getAttribute("urealname").toString();
    }

    //  输入账号密码，登陆账号
    @PostMapping("/login")
    public Result<User> loginController(@RequestBody UserRequest userRequest, HttpServletRequest request) throws Exception {
        Long userid = userRequest.getUid();
        String password = userRequest.getPw();
        System.out.println(userRequest);
        if (userid == null || userid <= 0l ) {
            throw new ParameterException("userid为null或数值非法");
        }
        if (password == null) {
            throw new ParameterException("password为null");
        }
        if (password.length() > 15 || password.length() < 6 || password.length() < 0) {
            throw new ParameterException("password长度非法");
        }
        User user = userService.loginService(userid, password);
        JSONObject jsonObject = new JSONObject();
        if (user != null) {
            if (user.getUNickname() != null) {
                String token = cryTokenController(userid);//加密账号
//                DecodedJWT verify = decTokenController(token);
//                Long uid = verify.getClaim("userid").asLong();
                Long uid = decTokenController(token);//解密账号
                jsonObject.put("token", token);
                jsonObject.put("uid", uid);
                return Result.success(HttpStatus.SUCCESS, "操作成功", jsonObject);
            }
            return Result.error(HttpStatus.NULL_ERROR, "用户信息未完善", Integer.parseInt("1"));
        } else {
            return Result.error(HttpStatus.NULL_ERROR, "账号或密码错误，请重新输入。", Integer.parseInt("0"));
        }
    }

    //  输入账号密码，登陆账号
    @PostMapping("/loginAfterPerfectInfo")
    public Result loginAfterPerfectInfo(@RequestBody UserRequest userRequest) throws Exception {
        User user = new User();
        user.setUId(userRequest.uid);
        user.setUNickname(userRequest.nickname);
        user.setUGender(userRequest.getGender());
        user.setUPhone(userRequest.getPhone());
        user.setUMail(userRequest.email);
        user.setUIntro(userRequest.getIntro());
        user.setUAbility(userRequest.getAbility());
        System.out.println(user);
        if (user == null || user.getUId() <= 0l) {
            throw new ParameterException("userid为null或数值非法");
        }
        String msg = userService.loginWithPerfectInfo(user);
        JSONObject jsonObject = new JSONObject();
        if (msg.equals("1")) {
            String token = cryTokenController(user.getUId());//加密账号
            Long uid = decTokenController(token);//解密账号
            jsonObject.put("token", token);
            jsonObject.put("uid", uid);
            return Result.success(HttpStatus.SUCCESS, "操作成功", jsonObject);
        } else {
            return Result.error(HttpStatus.NULL_ERROR, msg);
        }
    }

    //加密账号
    @RequestMapping("/cryptographicToken")
    public String cryTokenController(Long userid) throws ParameterException {
        if (userid == null || userid <= 0l) {
            throw new ParameterException("userid为null或数值非法");
        }
        String token = null;
//                if(userid != null){
        token = Token.sign(userid);//加密token
        return token;
//                }
//                else{
//                    return "账号为空";
//                }
    }

    //解密账号
    @RequestMapping("/decryptionToken")
    public Long decTokenController(String token) throws ParameterException {
        if (token == null || token.equals("")) {
            throw new ParameterException("token为空");
        }
        Long userid = null;
//                if(token != null){
        DecodedJWT verify = Token.verify(token);//解密账号
        userid = verify.getClaim("uid").asLong();//将解密得到的账号信息存到userid中
        return userid;
//                }
//                else{
//                    Long tokenerro = Long.valueOf("token为空");
//                    return tokenerro;
//                }
    }


    //    修改个人信息
    @RequestMapping("/changeInfo")
    public Result<User> changeInfoController(@RequestBody ModifyUserInfoRequest modifyUserInfoRequest) throws ParameterException {
        Long uid = modifyUserInfoRequest.getUid();
        String unickname = modifyUserInfoRequest.getNickname();
        String urealname = modifyUserInfoRequest.getRealname();
        String ugender = modifyUserInfoRequest.getGender();
        String uphone = modifyUserInfoRequest.getPhone();
        String umail = modifyUserInfoRequest.getEmail();
        String uintro = modifyUserInfoRequest.getIntro();
        String uability = modifyUserInfoRequest.getAbility();
        if (modifyUserInfoRequest == null) {
            throw new ParameterException("userRequest为null");
        }
        if (uid == null || uid <= 0l ) {
            throw new ParameterException("uid为null或数值非法");
        }
        if (unickname == null || unickname.equals("") ||
                urealname == null || urealname.equals("") ||
                ugender == null || ugender.equals("") ||
                uphone == null || uphone.equals("") ||
                umail == null || umail.equals("") ||
                uability == null || uability.equals("")) {
            System.out.println(modifyUserInfoRequest);
            throw new ParameterException("userRequest的必要属性含空值");
        }
        if (umail == null || umail.equals("")) {
            throw new ParameterException("email为空");
        }
        if (!umail.contains("@")) {
            throw new ParameterException("email值非法");
        }
        ModifyUserInfoRequest result = userService.changeInfoService(uid, unickname, urealname, ugender, uphone, umail, uintro, uability);
        if (result != null) {
            return Result.success(HttpStatus.SUCCESS, "修改成功", result);
        } else {
            return Result.error("修改有误！");
        }
    }

    //        通过用户登陆的账号uid显示个人信息
    @RequestMapping("/getUserInfo")
    public Result<User> getUserInfo(HttpServletRequest request) throws ParameterException {
        String token = request.getHeader("token");
        Long userid = null;
        if (token == null) {
            throw new ParameterException("未提供包含token的Authorization信息");
        }
        DecodedJWT verify = Token.verify(token);
        userid = verify.getClaim("uid").asLong();
        User user = userService.getUserById(userid);
        if (user != null) {
            return Result.success(HttpStatus.SUCCESS, "查找成功", user);
        } else {
            return Result.error("查找失败");
        }
    }

    /**
     * 根据ID查询姓名
     *
     * @param id
     * @return
     */
    @GetMapping("/getUsernameById")
    public Result getUsernameById(long id) {
        String name =
                userService.getUsenameById(id);
        if (name == null) {
            return Result.success("查询失败,"
                    + "请检查学号/工号是否填写正确");
        }
        return Result.success("查询成功!", name);
    }

}
